package com.ubb.dbms.core.fileManagers.indexFileManager.bPlusTree;

import java.nio.ByteBuffer;

import com.ubb.dbms.core.checker.DomainObjectChecker;
import com.ubb.dbms.core.fileManagers.indexFileManager.IndexFileIO;

public class NodeConverter {
	
	/**
	 * 	Convert byte[] to {@link Node}.
	 * 
	 * @param row
	 * @param nodeOffset
	 * @param indexFileIO 
	 * @return
	 */
	public static Node toNode(byte[] row, int nodeOffset, IndexFileIO indexFileIO){
		Node node = new Node(indexFileIO);
//		io.insertRow(new byte[]{1,  3,  0,0,0,3, 0,0,0,21,  0,0,0,2, 0,0,0,45,  0,0,0,5, 0,0,0,71,  0,0,0,0});
		node.setmIsLeafNode(row[0] != 0);
		node.setmNumKeys(row[1]);
		node.setRowNr(nodeOffset);
		if (node.ismIsLeafNode()){
			for (int i = 0; i < row[1]; i++){
				 node.setmObject(ByteBuffer.wrap(row, i*DomainObjectChecker.DEFAULT_INT_LENGTH*2+2, DomainObjectChecker.DEFAULT_INT_LENGTH).getInt(), i);
			}
			for (int i = 0; i < row[1]; i++){
				 node.setmKey(ByteBuffer.wrap(row, i*DomainObjectChecker.DEFAULT_INT_LENGTH*2+2+DomainObjectChecker.DEFAULT_INT_LENGTH, DomainObjectChecker.DEFAULT_INT_LENGTH).getInt(), i);
			}
			node.setmNextNode(ByteBuffer.wrap(row, row.length-DomainObjectChecker.DEFAULT_INT_LENGTH, DomainObjectChecker.DEFAULT_INT_LENGTH).getInt());
		} else {
			for (int i = 0; i <= row[1]; i++){
				 node.setmChildNode(ByteBuffer.wrap(row, i*DomainObjectChecker.DEFAULT_INT_LENGTH*2+2, DomainObjectChecker.DEFAULT_INT_LENGTH).getInt(), i);
			}
			for (int i = 0; i < row[1]; i++){
				 node.setmKey(ByteBuffer.wrap(row, i*DomainObjectChecker.DEFAULT_INT_LENGTH*2+2+DomainObjectChecker.DEFAULT_INT_LENGTH, DomainObjectChecker.DEFAULT_INT_LENGTH).getInt(), i);
			}
		}
		return node;
	}
	
	/**
	 * 	Convert {@link Node} to byte[].
	 * 
	 * @param node
	 * @param rowLength
	 * @return
	 */
	public static byte[] toByteArray(Node node, int rowLength) {
		byte[] byteArray = new byte[rowLength];
		byteArray[0] = (byte) (node.ismIsLeafNode() ? 1 : 0);
		byteArray[1] = (byte) node.getmNumKeys();
		if (node.ismIsLeafNode()) {
			for (int i = 0; i < node.getmNumKeys(); i++){
				byte[] object = ByteBuffer.allocate(DomainObjectChecker.DEFAULT_INT_LENGTH).putInt((Integer)node.getmObject(i)).array();
				byteArray[i * 8 + 2 + 0] = object[0];
				byteArray[i * 8 + 2 + 1] = object[1];
				byteArray[i * 8 + 2 + 2] = object[2];
				byteArray[i * 8 + 2 + 3] = object[3];
				byte[] key = ByteBuffer.allocate(DomainObjectChecker.DEFAULT_INT_LENGTH).putInt((int)node.getmNumKey(i)).array();
				byteArray[i * 8 + 2 + 4 + 0] = key[0];
				byteArray[i * 8 + 2 + 4 + 1] = key[1];
				byteArray[i * 8 + 2 + 4 + 2] = key[2];
				byteArray[i * 8 + 2 + 4 + 3] = key[3];
			}
			byte[] nextNodeOffset = ByteBuffer.allocate(DomainObjectChecker.DEFAULT_INT_LENGTH).putInt((int)node.getmNextNodeOffset()).array();
			byteArray[rowLength - 4 + 0] = nextNodeOffset[0];
			byteArray[rowLength - 4 + 1] = nextNodeOffset[1];
			byteArray[rowLength - 4 + 2] = nextNodeOffset[2];
			byteArray[rowLength - 4 + 3] = nextNodeOffset[3];
		} else {
			for (int i = 0; i <= node.getmNumKeys(); i++){
				byte[] object = ByteBuffer.allocate(DomainObjectChecker.DEFAULT_INT_LENGTH).putInt((int)node.getmChildNodeOffset(i)).array();
				byteArray[i * 8 + 2 + 0] = object[0];
				byteArray[i * 8 + 2 + 1] = object[1];
				byteArray[i * 8 + 2 + 2] = object[2];
				byteArray[i * 8 + 2 + 3] = object[3];
				if (i != node.getmNumKeys()) {
					byte[] key = ByteBuffer.allocate(DomainObjectChecker.DEFAULT_INT_LENGTH).putInt((int)node.getmNumKey(i)).array();
					byteArray[i * 8 + 2 + 4 + 0] = key[0];
					byteArray[i * 8 + 2 + 4 + 1] = key[1];
					byteArray[i * 8 + 2 + 4 + 2] = key[2];
					byteArray[i * 8 + 2 + 4 + 3] = key[3];
				}
			}
		}
		return byteArray;
	}
}
